package org.example.liuy.controller;

import com.sun.net.httpserver.HttpExchange;
import lombok.extern.slf4j.Slf4j;
import org.example.liuy.annotation.PostMapping;
import org.example.liuy.annotation.RestController;
import org.example.liuy.exception.BusinessException;
import org.example.liuy.service.StakeManager;
import org.example.liuy.service.session.IntelligentSessionService;

import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

/**
 * 投注服务控制器
 */
@Slf4j
@RestController
public class StakeController extends BaseController {
    private final StakeManager stakeManager;

    public StakeController(IntelligentSessionService sessionManager, StakeManager stakeManager) {
        super(sessionManager);
        this.stakeManager = stakeManager;
    }

    /**
     * 处理投注请求
     *
     * @param exchange HTTP交换对象
     * @throws IOException IO异常
     */
    @PostMapping("/{betOfferId}/stake")
    public void handleStakeRequest(HttpExchange exchange) throws IOException {
        try {
            // 解析请求参数
            String sessionKey = extractSessionKey(exchange);
            Integer betOfferId = extractBetOfferId(exchange);
            Integer customerId = extractCustomerIdFromSession(sessionKey);
            double stake = parseStakeAmount(exchange);

            // 提交投注
            stakeManager.submitStake(betOfferId, customerId, stake, sessionKey);
            sendResponse(exchange, 200, "Stake accepted");
        } catch (BusinessException e) {
            handleBusinessException(exchange, e);
        } catch (Exception e) {
            log.error("Stake submission failed", e);
            sendResponse(exchange, 500, "Internal Server Error");
        }
    }

    /**
     * 从查询参数中提取会话键
     */
    private String extractSessionKey(HttpExchange exchange) throws BusinessException {
        String query = exchange.getRequestURI().getQuery();
        if (query == null || !query.startsWith("sessionkey=")) {
            throw new BusinessException(BusinessException.PARAM_ERROE, "Missing session key");
        }
        return query.substring(11); // "sessionkey=".length()
    }

    /**
     * 从路径中提取投注项ID
     */
    private Integer extractBetOfferId(HttpExchange exchange) throws BusinessException {
        String[] pathParts = exchange.getRequestURI().getPath().split("/");
        if (pathParts.length < 3) {
            throw new BusinessException(BusinessException.PARAM_ERROE, "Invalid bet offer ID");
        }

        try {
            return Integer.valueOf(pathParts[pathParts.length - 2]);
        } catch (NumberFormatException e) {
            throw new BusinessException(BusinessException.PARAM_ERROE, "Invalid bet offer ID format");
        }
    }

    /**
     * 从会话中提取客户ID
     */
    private Integer extractCustomerIdFromSession(String sessionKey) throws BusinessException {
        Integer customerId = sessionManager.getCustomerIdFromSession(sessionKey);
        if (customerId == null) {
            throw new BusinessException(BusinessException.PARAM_ERROE, "Invalid session key");
        }
        return customerId;
    }

    /**
     * 解析投注金额
     */
    private double parseStakeAmount(HttpExchange exchange) throws IOException, BusinessException {
        String requestBody = readRequestBody(exchange);
        if (requestBody == null || requestBody.isEmpty()) {
            throw new BusinessException(BusinessException.PARAM_ERROE, "Missing stake amount");
        }

        try {
            return Double.parseDouble(requestBody);
        } catch (NumberFormatException e) {
            return parseFormData(requestBody);
        }
    }

    /**
     * 解析表单数据
     */
    private double parseFormData(String formData) throws BusinessException {
        String[] pairs = formData.split("&");

        for (String pair : pairs) {
            String[] keyValue = pair.split("=", 2);
            if (keyValue.length >= 1 && "stake".equals(keyValue[0])) {
                if (keyValue.length == 2 && keyValue[1] != null && !keyValue[1].isEmpty()) {
                    try {
                        String value = URLDecoder.decode(keyValue[1], StandardCharsets.UTF_8);
                        return Double.parseDouble(value.trim());
                    } catch (Exception e) {
                        throw new BusinessException(BusinessException.PARAM_ERROE, "Invalid stake amount format");
                    }
                } else {
                    throw new BusinessException(BusinessException.PARAM_ERROE, "Missing stake amount value");
                }
            }
        }

        throw new BusinessException(BusinessException.PARAM_ERROE, "Missing stake parameter in form data");
    }

    /**
     * 处理业务异常
     */
    private void handleBusinessException(HttpExchange exchange, BusinessException e) throws IOException {
        switch (e.getStatusCode()) {
            case BusinessException.PARAM_ERROE:
                sendResponse(exchange, 400, e.getMessage());
                break;
            case BusinessException.SYSTEM_MAXLIMIT:
                sendResponse(exchange, 429, e.getMessage()); // Too Many Requests
                break;
            default:
                sendResponse(exchange, 400, e.getMessage());
        }
    }
}
